package com.sky.advice;

import com.sky.annotation.AutoFill;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.time.LocalDateTime;

/**
 * 进行公共字段填充的切面类
 */
@Aspect
@Component
@Slf4j
public class AutoFillAspect {
    /**
     * 切点表达式提取
     * 拦截com.sky.mappe包下所有带Autofill注解的方法
     */
    @Pointcut("execution(* com.sky.mapper.*.*(..)) &&@annotation(com.sky.annotation.AutoFill)")
    public void autoFillPointCut() {}

    /**
     * 自动填充公共字段，在切面方法执行之前
     */
    @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint) throws Exception{
        log.info("开始进行公共字段自动填充");
        Object entity = joinPoint.getArgs()[0];//获取实体类对象
        Class<?> entityCls = entity.getClass();
        //插入和更新操作，都要为修改时间和修改人赋值
        Field updateTime = entityCls.getDeclaredField("updateTime");
        Field updateUser = entityCls.getDeclaredField("updateUser");
        updateTime.setAccessible(true);
        updateUser.setAccessible(true);
        updateTime.set(entity, LocalDateTime.now());
        updateUser.set(entity, BaseContext.getCurrentId());
        log.info("{}",BaseContext.getCurrentId());
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();//切点获得的签名需要向下转型，方便调用getMethod方法
        AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);//只有通过Method才能获得注解
        if (autoFill.value()== OperationType.INSERT) {//如果是插入操作，需要为创建人和创建时间赋值
            Field createTime = entityCls.getDeclaredField("createTime");
            createTime.setAccessible(true);
            createTime.set(entity, LocalDateTime.now());
            Field createUser = entityCls.getDeclaredField("createUser");
            createUser.setAccessible(true);
            createUser.set(entity, BaseContext.getCurrentId());
        }
        log.info("实体对象：{}",entity);
    }
}
